/**
 * 
 */
package neptune.web.server.repository;

import it.robertobifulco.ias.Operation;
import it.robertobifulco.ias.OperationRepository;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import neptune.web.server.Debug;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * @author Roberto Bifulco [RobertoBifulco.it] [info@robertoBifulco.it]
 * 
 */
public class XMLOperationsRepository implements OperationRepository {

	private String operationFilePath = "operations.xml";

	public XMLOperationsRepository(String operationFilePath) {
		super();
		this.operationFilePath = operationFilePath;
	}

	public void writeOperations(Operation[] operations) {

		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();

			Document document = builder.newDocument();

			document.setXmlVersion("1.0");

			Element rootNode = document.createElement("operations");
			document.appendChild(rootNode);

			Element operation;
			Element description;
			for (int i = 0; i < operations.length; ++i) {
				operation = document.createElement("operation");
				operation.setAttribute("id", operations[i].getID());
				description = document.createElement("description");
				description.setTextContent(operations[i].getDescription());
				operation.appendChild(description);
				rootNode.appendChild(operation);
			}

			// ///////////////
			// Output the XML

			File xmlFile = new File(this.operationFilePath);
			// set up a transformer
			TransformerFactory transfac = TransformerFactory.newInstance();
			Transformer trans = transfac.newTransformer();
			trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
			trans.setOutputProperty(OutputKeys.INDENT, "yes");
			trans.setOutputProperty(OutputKeys.STANDALONE, "yes");
			trans.setOutputProperty(
					"{http://xml.apache.org/xslt}indent-amount", "2");

			// create string from xml tree
			StringWriter sw = new StringWriter();
			StreamResult result = new StreamResult(sw);
			DOMSource source = new DOMSource(document);
			trans.transform(source, result);
			String xmlString = sw.toString();

			xmlFile.createNewFile();
			FileWriter writer = new FileWriter(xmlFile);
			writer.write(xmlString);
			writer.flush();

		} catch (ParserConfigurationException e) {
			Debug.printTrace(e);
			throw new RuntimeException(e);
		} catch (IOException e) {
			Debug.printTrace(e);
			throw new RuntimeException(e);
		} catch (TransformerConfigurationException e) {
			Debug.printTrace(e);
			throw new RuntimeException(e);
		} catch (TransformerException e) {
			Debug.printTrace(e);
			throw new RuntimeException(e);
		}

	}

	public void updateOperationsList(String[] operationIdentifiers,
			String[] operationDescriptions) {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();

			Document document = builder.newDocument();

			document.setXmlVersion("1.0");

			Element rootNode = document.createElement("operations");
			document.appendChild(rootNode);

			Element operation;
			Element description;
			for (int i = 0; i < operationIdentifiers.length; ++i) {
				operation = document.createElement("operation");
				operation.setAttribute("id", operationIdentifiers[i]);
				description = document.createElement("description");
				description.setTextContent(operationDescriptions[i]);
				operation.appendChild(description);

				rootNode.appendChild(operation);
			}


			// ///////////////
			// Output the XML

			File xmlFile = new File(this.operationFilePath);
			// set up a transformer
			TransformerFactory transfac = TransformerFactory.newInstance();
			Transformer trans = transfac.newTransformer();
			trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
			trans.setOutputProperty(OutputKeys.INDENT, "yes");
			trans.setOutputProperty(OutputKeys.STANDALONE, "yes");
			trans.setOutputProperty(
					"{http://xml.apache.org/xslt}indent-amount", "2");

			// create string from xml tree
			StringWriter sw = new StringWriter();
			StreamResult result = new StreamResult(sw);
			DOMSource source = new DOMSource(document);
			trans.transform(source, result);
			String xmlString = sw.toString();

			xmlFile.createNewFile();
			FileWriter writer = new FileWriter(xmlFile);
			writer.write(xmlString);
			writer.flush();

		} catch (ParserConfigurationException e) {
			throw new RuntimeException(e);
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (TransformerConfigurationException e) {
			throw new RuntimeException(e);
		} catch (TransformerException e) {
			throw new RuntimeException(e);
		}

	}

}
